package com.lingz.manager.common.utils;

import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @author wuchangwen
 * @desc 文件操作的工具类
 * 
 */
public class FileUtils {
	private static final int BUFFER_SIZE = 100 * 1024;
	private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);
	/**
	 * 根据路径创建文件夹
	 * 
	 * @param dirPath
	 * @throws Exception
	 */
	public static void mkDirs(String dirPath) throws Exception {
		if (StringUtils.isBlank(dirPath)) {
			throw new Exception("文件夹路径不能为空");
		}
		File f = new File(dirPath);
		if (!f.exists()) {
			f.mkdirs();
		}
	}

	/**
	 * 删除指定路径的文件
	 * 
	 * @param dirPath
	 * @throws Exception
	 */
	public static void deleteDir(String dirPath) throws Exception {
		if (StringUtils.isBlank(dirPath)) {
			throw new Exception("文件夹路径不能为空");
		}
		File f = new File(dirPath);
		if (f.exists()) {
			deleteAllFiles(f);
		}
	}

	/**
	 * 递归删除文件
	 * 
	 * @param file
	 */
	public static void deleteAllFiles(File file) {
		if (file.isDirectory()) {
			for (File child : file.listFiles()) {
				deleteAllFiles(child);
			}
		}
		file.delete();
	}

	/**
	 * 将文件保存至指定目录
	 * 
	 * @param destPath
	 * @param file
	 * @throws Exception
	 */
	public static void saveFile(String destPath, File file) throws Exception {
		org.apache.commons.io.FileUtils.copyFile(file, new File(destPath));
	}


	/**
	 * 	移动文件到指定位置
	 * @param fileFullNameCurrent 要移动的文件全路径
	 * @param fileFullNameTarget 移动到目标位置的文件全路径
	 * @return 是否移动成功， true：成功；否则失败
	 */
	public static Boolean moveFileToTarget(String fileFullNameCurrent,String fileFullNameTarget) 		{
		boolean ismove = false;

		File oldName = new File(fileFullNameCurrent);

		if (!oldName.exists()) {
			logger.warn("{}","要移动的文件不存在！");
			return ismove;
		}

		if (oldName.isDirectory()) {
			logger.warn("{}","要移动的文件是目录，不移动！");
			return false;
		}

		File newName = new File(fileFullNameTarget);

		if (newName.isDirectory()) {
			logger.warn("{}","移动到目标位置的文件是目录，不能移动！");
			return false;
		}

		String pfile = newName.getParent();
		File pdir = new File(pfile);

		if (!pdir.exists()) {
			pdir.mkdirs();
			logger.warn("{}","要移动到目标位置文件的父目录不存在，创建：" + pfile);
		}

		ismove = oldName.renameTo(newName);
		return ismove;
	}
//
//	public static void main(String[] args){
//
//		String filePath = "D:\\test\\b.txt";
//		String filePathNew = "D:\\test\\c\\d\\b.txt";
//
//		Boolean ismove = moveFileToTarget(filePath, filePathNew);
//
//		System.out.println(ismove);
//		System.out.println("over");
//	}




	/**
	 * wenjian 扩展名是否为指定的扩展名
	 * 
	 * @param fileName
	 * @param suffix
	 */
	public static boolean isSuffixMatchs(String fileName, String suffix) {
		if (StringUtils.isBlank(fileName) || StringUtils.isBlank(suffix)) {
			return false;
		}
		if (StringUtils.equalsIgnoreCase(getFileSuffix(fileName), suffix)) {
			return true;
		}
		return false;
	}

	/**
	 * 获取文件的扩展名
	 * 
	 * @param fileName
	 * @return
	 */
	public static String getFileSuffix(String fileName) {
		if (StringUtils.isBlank(fileName)) {
			return null;
		}
		return StringUtils.substringAfter(fileName, ".");
	}
	/**
	 * 构建properties
	 *
	 * @return : java.util.Map<java.lang.String,java.lang.Object>
	 * @author zfxiang [xiangzf@engine3d.com]
	 * @date 2020/6/9 10:52
	 */
	private static Map<String, Object> makeBaseProperties() {
		Map<String, Object> properties = new HashMap();
		properties.put("polygonType", "polygon");
		properties.put("fill", "#ffffff");
		properties.put("fill-opacity", 0.5);
		properties.put("stroke-width", 2);
		properties.put("stroke-opacity", 1);
		properties.put("stroke", "#408080");
		properties.put("name", "");
		return properties;
	}
	public static void appendFile(InputStream in, File destFile) throws IOException {
		OutputStream out = null;
		try {
			// plupload 配置了chunk的时候新上传的文件append到文件末尾
			if (destFile.exists()) {
				out = new BufferedOutputStream(new FileOutputStream(destFile, true), BUFFER_SIZE);
			} else {
				out = new BufferedOutputStream(new FileOutputStream(destFile), BUFFER_SIZE);
			}
			in = new BufferedInputStream(in, BUFFER_SIZE);

			int len = 0;
			byte[] buffer = new byte[BUFFER_SIZE];
			while ((len = in.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (null != in) {
					in.close();
				}
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	public static InputStream base64ToInputStream(String base64) {
		try {
			String[] baseStrs = base64.split(",");

			BASE64Decoder decoder = new BASE64Decoder();
			byte[] b = new byte[0];
			b = decoder.decodeBuffer(baseStrs[1]);

			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {
					b[i] += 256;
				}
			}
			return new ByteArrayInputStream(b);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
	private static void geo2shp(String shpFilePath,
								String geojsonPath) {
		String picCommend = "ogr2ogr -f \"ESRI Shapefile\" " + shpFilePath
				+ " " + geojsonPath;
		runCmd(picCommend);
	}

	private static void runCmd(String command) {
		try {
			Runtime rt = Runtime.getRuntime();
			Process proc = rt.exec(command);
			InputStream stderr = proc.getErrorStream();
			InputStreamReader isr = new InputStreamReader(stderr);
			BufferedReader br = new BufferedReader(isr);
			String line = null;
			System.out.println("<ERROR>");
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
			System.out.println("</ERROR>");
			int exitVal = proc.waitFor();
			System.out.println("Process exitValue: " + exitVal);
		} catch (Throwable t) {
			System.out.println(t);
			t.printStackTrace();
		}

	}

	public static JSONObject shpToGeojson(String workSpacePath, String shpFileName) throws IOException {
		String filename = shpFileName.substring(0, shpFileName.lastIndexOf("."));
		//使用gdal的工具，执行cmd命令
		Runtime rt = Runtime.getRuntime();
		String cmd = "ogr2ogr -t_srs EPSG:4326 -f GeoJson " + workSpacePath + filename + ".geojson" + " " + workSpacePath + shpFileName;
		Process p = rt.exec(cmd);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		File file = new File(workSpacePath + filename + ".geojson");
		String text = org.apache.commons.io.FileUtils.readFileToString(file, "UTF-8");
		JSONObject jsonObject = JSONObject.parseObject(text);
		return jsonObject;
	}

	//    public static void main(String[] args) throws IOException, InterruptedException {
	String geojsonStr = "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[10.781662469505527,58.99727341375908,0],[10.782110957068376,58.99717187847401,0],[10.782174283542597,58.99681031168689,1.3222238854040097e-9],[10.78180984509706,58.99681275056772,9.313225746154785e-10],[10.781519467071563,58.996839782937315,9.313225746154785e-10],[10.781436643701255,58.99701867044865,9.313225746154785e-10],[10.781341118892644,58.99714725688093,9.313225746154785e-10]]]}}]}";
	String shpFilePath = "e:\\test";
	String uuid = UUID.randomUUID().toString();
	//geojsonToShp(shpFilePath, uuid, geojsonStr);
//        String workSpacePath = "C:\\Users\\admin\\Desktop\\";
//        String filename = "33ff8780-8c8c-45b1-a933-685e1284e9f4";
//        JSONObject jsonObject = shpToGeojson(workSpacePath, filename);
//        System.out.println("转换成功！" );
//    }

	public static void downLoadNew(HttpServletResponse response, String path, String name) {
		// 以流的形式下载文件。
		InputStream fis = null;
		File file = new File(path);
		try {
			fis = new BufferedInputStream(new FileInputStream(file));
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
			// 设置response的Header
			response.setContentType("application/x-download");
			response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "utf-8"));
			response.addHeader("Content-Length", "" + file.length());
			OutputStream toClient = response.getOutputStream();
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static File MultipartFileToFile(MultipartFile multiFile) {
		// 获取文件名
		String fileName = multiFile.getOriginalFilename();
		// 获取文件后缀
		String prefix = fileName.substring(fileName.lastIndexOf("."));
		// 若须要防止生成的临时文件重复,能够在文件名后添加随机码

		try {
			File file = File.createTempFile(fileName, prefix);
			multiFile.transferTo(file);
			return file;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 编码文件名
	 * 日期路径 + UUID
	 * 示例：fileName=2022/11/18/统计报表1668758006562.txt
	 */
	public static final String extractUploadFilename(MultipartFile file)
	{
		String fileName = file.getOriginalFilename();
		// 注意，这里需要加上 \\ 将 特殊字符 . 转意 \\. ,否则异常
		String[] fileArray = fileName.split("\\.");
		fileName = datePath() + "/" + fileArray[0]+System.currentTimeMillis()+"."+fileArray[1];
		return fileName;
	}

	/**
	 * 日期路径 即年/月/日 如2018/08/08
	 */
	public static final String datePath() {
		Date now = new Date();
		return DateFormatUtils.format(now, "yyyy/MM/dd");
	}
}
